﻿using System;
using Platformer_Example.Content.Images.Player;
using Platformer_Example.Controller.Input;
using Transformable_Engine_v2.Engine.Time;
using Transformable_Engine_v2.Engine.Transformable_Math.Geometry;

namespace Platformer_Example.Controller.Character.Player
{
    public partial class Player
    {
        #region Throw

        private Timer _throwTimer;

        protected override void CreateThrowStateObjects()
        {
            AddTimers(_throwTimer = new Timer(300, false, EndThrow));
        }

        private void EndThrow()
        {
            ChangeState(State.Idle);
        }

        protected override void InitializeThrowState()
        {
            _throwTimer.Reset();

            Character.Sprite = SpritesheetPlayer.GetSprite(SpritesheetPlayer.IdleState.Throw);
            Character.OriginAbsolute = new TE_Vector2(8, 32);

            ThrowCarriedObject(new TE_Vector2(17, -15), new TE_Vector2(0.5f, 0).ToGridbound());
        }

        protected override void OnKeyPressThrow(InputState.Key key)
        {
        }

        protected override void OnKeyReleaseThrow(InputState.Key key)
        {
        }

        protected override void UpdateThrowState(TimeSpan gameTime)
        {
        }

        protected override void EndThrowState()
        {
        }

        #endregion

        #region Air Throw

        private Timer _airThrowTimer;

        protected override void CreateAirThrowStateObjects()
        {
            AddTimers(_airThrowTimer = new Timer(300, false, EndAirThrow));
        }

        private void EndAirThrow()
        {
            ChangeState(State.Fall);
        }

        protected override void InitializeAirThrowState()
        {
            _airThrowTimer.Reset();
            Jump(-0.5f);

            Character.Sprite = SpritesheetPlayer.GetSprite(SpritesheetPlayer.JumpState.Throw);
            Character.OriginAbsolute = new TE_Vector2(8, 32);

            ThrowCarriedObject(new TE_Vector2(17, -3), new TE_Vector2(1, 0.25f).ToGridbound());
        }

        protected override void UpdateAirThrowState(TimeSpan gameTime)
        {
        }

        protected override void EndAirThrowState()
        {
        }

        protected override void OnKeyPressAirThrow(InputState.Key key)
        {
        }

        protected override void OnKeyReleaseAirThrow(InputState.Key key)
        {
        }

        #endregion

        #region Long Throw
        private Timer _longThrowTimer;

        protected override void CreateLongThrowStateObjects()
        {
            AddTimers(_longThrowTimer = new Timer(300, false, EndLongThrow));
        }

        private void EndLongThrow()
        {
            ChangeState(State.Idle);
        }

        protected override void InitializeLongThrowState()
        {
            _longThrowTimer.Reset();

            Character.Sprite = SpritesheetPlayer.GetSprite(SpritesheetPlayer.WalkState.Throw);
            Character.OriginAbsolute = new TE_Vector2(8, 32);

            ThrowCarriedObject(new TE_Vector2(17, -25), new TE_Vector2(1, -0.5f).ToGridbound());
        }

        protected override void UpdateLongThrowState(TimeSpan gameTime)
        {
        }

        protected override void EndLongThrowState()
        {
        }

        protected override void OnKeyPressLongThrow(InputState.Key key)
        {
        }

        protected override void OnKeyReleaseLongThrow(InputState.Key key)
        {
        }

        #endregion

        public void ThrowCarriedObject(TE_Vector2 positionOffset, TE_Vector2 velocity)
        {
            var thrownObject = CarriedObject.GetThrownObject();
            if (CurrentDirection == Direction.Left)
            {
                positionOffset = positionOffset.FlipHorizontally;
                velocity = velocity.FlipHorizontally;
            }
            thrownObject.SetPushback(velocity);
                
            thrownObject.ChangeMap(CurrentMap.Id, (AbsolutePosition + positionOffset).AsGridBound());
            
            CarriedObject.Die();
            CarriedObject = null;
        }
    }
}